package com.shopoo.oauth.infrastructure.repository;

import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shopoo.dto.PageResponse;
import com.shopoo.exception.BizException;
import com.shopoo.oauth.domain.entity.Role;
import com.shopoo.oauth.domain.entity.User;
import com.shopoo.oauth.domain.enums.StatusEnum;
import com.shopoo.oauth.domain.repository.UserRepository;
import com.shopoo.oauth.domain.valueobject.UserAuth;
import com.shopoo.oauth.domain.valueobject.UserQuery;
import com.shopoo.oauth.infrastructure.converter.InfrastructureConverter;
import com.shopoo.oauth.infrastructure.database.dataobject.OauthUser;
import com.shopoo.oauth.infrastructure.database.mapper.RoleMapper;
import com.shopoo.oauth.infrastructure.database.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Repository;

/**
 * @Description 用户仓库
 * @Date 2020/5/24 1:54 下午
 * @Author <a href="mailto:android_li@sina.cn">Joe</a>
 **/
@Repository
public class UserRepositoryImpl extends ServiceImpl<UserMapper, OauthUser> implements UserDetailsService, UserRepository {

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Override
    public void add(User user) {
        try {
            user.generateId();
            user.cryptPassword();
            OauthUser oauthUser = InfrastructureConverter.INSTANCE.toOauthUser(user);
            super.save(oauthUser);
        } catch (DuplicateKeyException e) {
            throw new BizException("用户名或电话号码已被使用，请检查");
        }
    }

    @Override
    public void removeByUserId(String userId) {
        super.removeById(userId);
    }

    @Override
    public UserAuth getByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    @Override
    public PageResponse<User> getPageByConditions(UserQuery user) {
        Page<OauthUser> page = PageHelper.startPage(user.getPageNum(), user.getPageSize());
        LambdaQueryWrapper<OauthUser> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(user.getUserId())) {
            queryWrapper.eq(OauthUser::getUserId, user.getUserId());
        }
        if (StringUtils.isNotBlank(user.getUsername())) {
            queryWrapper.eq(OauthUser::getUsername, user.getUsername());
        }
        if (StringUtils.isNotBlank(user.getPhone())) {
            queryWrapper.eq(OauthUser::getPhone, user.getPhone());
        }
        List<OauthUser> list = super.list(queryWrapper);
        List<User> users = list.stream().map(oauthUser -> {
            return InfrastructureConverter.INSTANCE.toUser(oauthUser);
        }).collect(Collectors.toList());
        return PageResponse.of(users, page.getTotal(), page.getPageSize(), page.getPageNum());
    }

    @Override
    public List<User> getByConditions(UserQuery user) {
        LambdaQueryWrapper<OauthUser> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(user.getUserId())) {
            queryWrapper.eq(OauthUser::getUserId, user.getUserId());
        }
        if (StringUtils.isNotBlank(user.getUsername())) {
            queryWrapper.eq(OauthUser::getUsername, user.getUsername());
        }
        if (StringUtils.isNotBlank(user.getPhone())) {
            queryWrapper.eq(OauthUser::getPhone, user.getPhone());
        }
        List<OauthUser> list = super.list(queryWrapper);
        return list.stream().map(oauthUser -> {
            return InfrastructureConverter.INSTANCE.toUser(oauthUser);
        }).collect(Collectors.toList());
    }

    @Override
    public List<User> getUsers(UserQuery user) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(user.getUserId())) {
            queryWrapper.eq(User::getUserId, user.getUserId());
        }
        if (StringUtils.isNotBlank(user.getUsername())) {
            queryWrapper.likeRight(User::getUsername, user.getUsername());
        }
        if (StringUtils.isNotBlank(user.getNickname())) {
            queryWrapper.likeRight(User::getNickname, user.getNickname());
        }
        if (StringUtils.isNotBlank(user.getPhone())) {
            queryWrapper.likeRight(User::getPhone, user.getPhone());
        }
        if (user.getStatus() != null) {
            queryWrapper.eq(User::getStatus, user.getStatus());
        }
        queryWrapper.orderByDesc(User::getCreateTime);
        if (StringUtils.isNotBlank(user.getRoleName())) {
            QueryWrapper queryWrapper1 = new QueryWrapper();
            queryWrapper1.likeRight("roleName", user.getRoleName());
            return userMapper.findByUserInfo(queryWrapper1);
        }
        return userMapper.findUsers(queryWrapper);
    }

    @Override
    public User getByUserId(String userId) {
        OauthUser oauthUser = super.getById(userId);
        return InfrastructureConverter.INSTANCE.toUser(oauthUser);
    }

    @Override
    public List<User> getByRoleId(Long roleId) {
        return null;
    }

    @Override
    public void updateById(User user) {
        user.cryptPassword();
        OauthUser oauthUser = InfrastructureConverter.INSTANCE.toOauthUser(user);
        try {
            boolean flag = super.updateById(oauthUser);
            if (!flag) {
                throw new IllegalArgumentException("找不到用户【"+ user.getUserId()+"】信息！");
            }
        } catch (DuplicateKeyException e) {
            throw new BizException("用户名或电话号码已被使用，请检查");
        }
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserAuth user = userMapper.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("user [" + username + "] do not exist!");
        }
        if (user.getStatus() != StatusEnum.ENABLE.getValue()) {
            throw new BizException("用户已被禁用，请联系平台管理员");
        }
        List<Role> roles = roleMapper.findByUserId(user.getUserId());
        user.setAuthorities(roles);
        return user;
    }
}
